package com.kingmed.kmss.admin.modules.ums.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kingmed.kmss.admin.modules.ums.model.UmsAdmin;
import com.kingmed.kmss.admin.modules.ums.model.UmsOrganization;
import com.kingmed.kmss.admin.modules.ums.model.UmsResource;
import com.kingmed.kmss.admin.modules.ums.model.UmsRole;
import com.kingmed.kmss.admin.modules.ums.service.UmsAdminService;
import com.kingmed.kmss.admin.modules.ums.service.UmsOrganizationService;
import com.kingmed.kmss.admin.qc.AdminQc;
import com.kingmed.kmss.common.dto.admin.ums.*;
import com.kingmed.kmss.common.enums.admin.UserSource;
import com.kingmed.kmss.common.exception.BusinessException;
import com.kingmed.kmss.common.satoken.LoginHelper;
import com.kingmed.kmss.common.utils.BeanCopyUtils;
import com.kingmed.kmss.common.vo.CommonPage;
import com.kingmed.kmss.common.vo.CommonResponse;
import com.kingmed.kmss.common.vo.CommonResponseHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 后台用户表 前端控制器
 * </p>
 */
@RestController
@RequestMapping("/ums/user")
@Slf4j
@Api(tags = "ums用户管理")
public class UmsAdminController {

    @Autowired
    private UmsAdminService adminService;

    @Autowired
    private UmsOrganizationService organizationService;

    @ApiOperation(value = "用户注册")
    @PostMapping(value = "/register")
    @ResponseBody
    public CommonResponse<UmsAdmin> register(@RequestBody AdminRegisterDTO adminRegisterDto) {
        UmsAdmin admin = adminService.register(adminRegisterDto);
        if (admin == null) {
            return CommonResponseHelper.fail("注册失败，用户重复");
        }
        return CommonResponseHelper.success("注册成功", admin);
    }

    @ApiOperation(value = "用户登录")
    @PostMapping(value = "/login")
    @ResponseBody
    public CommonResponse<Object> login(@RequestBody AdminLoginDTO adminLoginDto) {
        throw new BusinessException("请从Auth模块登录");
    }

    // 登录后前端即发起调用，返回完整的admin info，包括有权限菜单、资源、角色、所属组织部门
    @ApiOperation(value = "获取当前登录用户信息")
    @GetMapping(value = "/info")
    @ResponseBody
    public CommonResponse<Map<String, Object>> getAdminInfo() {
        Map<String, Object> data = new HashMap<>();
        if (!StpUtil.isLogin()) {
            return CommonResponseHelper.unauthorized("未登录");
        }
        //基于token解析
        Long userId = LoginHelper.getUserIdByToken();
        LoginUserDTO loginUser = adminService.getAdminDTOByIdInCache(userId);
        data.put("token", loginUser.getToken());
        data.put("adminId", loginUser.getId());
        data.put("employeeNum", loginUser.getEmployeeNum());
        data.put("email", loginUser.getEmail());
        data.put("phone", loginUser.getPhone());
        data.put("nickName", loginUser.getNickName());
        data.put("username", loginUser.getUsername());
        data.put("avatar", loginUser.getAvatar());
        data.put("roles", loginUser.getRoles());// 角色
        data.put("resources", loginUser.getResources()); // 资源
        data.put("organizations", loginUser.getOrgs()); // 组织结构
        data.put("menusTree", loginUser.getMenusTree()); // 菜单树
        return CommonResponseHelper.success(data);
    }

    @ApiOperation(value = "分页查询-根据关键词")
    @GetMapping(value = "/list")
    public CommonResponse<CommonPage<AdminDTO>> list(@RequestParam(value = "keyword", required = false) String keyword,
                                  @RequestParam(value = "status", required = false) Integer status,
                                  @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                                  @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        Page<UmsAdmin> page = new Page<>(pageNum, pageSize);
        AdminQc adminQc = new AdminQc();
        adminQc.setUsername(keyword);
        adminQc.setStatus(status);
        Page<AdminDTO> result = adminService.pageDtoList(adminQc, page);
        return CommonResponseHelper.success(CommonPage.restPage(result));
    }

    @ApiOperation(value = "分页查询-根据多查询条件")
    @PostMapping(value = "/page")
    public CommonResponse<Page<AdminDTO>> page(@RequestBody AdminQc adminQc) {
        Page<UmsAdmin> page = new Page<>(adminQc.getPageNum(), adminQc.getPageSize());
        Page<AdminDTO> result = adminService.pageDtoList(adminQc, page);
        return CommonResponseHelper.success(result);
    }

    @ApiOperation(value = "不分页-根据条件全量查询用户及所属组织结构")
    @PostMapping(value = "/queryAll")
    @ResponseBody
    public CommonResponse<List<AdminDTO>> queryAll(@RequestBody AdminQc adminQc) {
        return CommonResponseHelper.success(adminService.queryAll(adminQc));
    }

    @ApiOperation(value = "不分页-根据员工号、用户名、姓名查询用户基础信息")
    @PostMapping(value = "/queryByCondition")
    @ResponseBody
    public CommonResponse<List<AdminDTO>> queryByCondition(@RequestBody AdminQc adminQc) {
        return CommonResponseHelper.success(adminService.queryByCondition(adminQc));
    }

    @ApiOperation(value = "根据用户ID用户详情")
    @GetMapping(value = "/get/{id}")
    public CommonResponse<AdminDTO> loadById(@PathVariable(value = "id") Long id) {
        UmsAdmin admin = adminService.getById(id);
        AdminDTO result = BeanCopyUtils.copy(admin, AdminDTO.class);
        if (result != null) {
            List<UmsOrganization> userOrgList = adminService.getOrgList(id);
            if (CollectionUtils.isNotEmpty(userOrgList)) {
                result.setOrganizations(BeanCopyUtils.copyList(userOrgList, OrganizationDTO.class));
                if (UserSource.CRM_USER.getUserType().equals(result.getUserSource())) {
                    result.setOrgFullName(organizationService.getAdminOrgFullName(userOrgList.get(0).getId()));
                }
            }
        }
        return CommonResponseHelper.success(result);
    }

    @ApiOperation(value = "根据用户username获取用户详情")
    @GetMapping(value = "/getByUsername")
    public CommonResponse<AdminDTO> loadByUsername(@RequestParam(name = "username") String username) {
        UmsAdmin admin = adminService.getAdminByUsername(username);
        return CommonResponseHelper.success(BeanCopyUtils.copy(admin, AdminDTO.class));
    }

    @ApiOperation("根据username查询用户信息")
    @PostMapping(value = "/listByUsername")
    public CommonResponse<List<AdminDTO>> listByUsername(@RequestBody List<String> usernameList) {
        List<UmsAdmin> adminList = adminService.getBaseMapper().selectList(new QueryWrapper<UmsAdmin>().lambda().in(UmsAdmin::getUsername, usernameList));
        return CommonResponseHelper.success(BeanCopyUtils.copyList(adminList, AdminDTO.class));
    }

    @ApiOperation(value = "用户是否登录")
    @PostMapping(value = "/isLogin")
    public CommonResponse<Boolean> isLogin() {
        boolean login = StpUtil.isLogin();
        return CommonResponseHelper.success(login);
    }

    @ApiOperation(value = "查询当前用户的Token信息")
    @GetMapping(value = "/tokenInfo")
    public CommonResponse<SaTokenInfo> tokenInfo() {
        return CommonResponseHelper.success(StpUtil.getTokenInfo());
    }

    @ApiOperation(value = "用户注销")
    @PostMapping(value = "/logout")
    public CommonResponse<String> logout() {
        StpUtil.logout();
        return CommonResponseHelper.success();
    }

    @ApiOperation("获取用户所有角色")
    @GetMapping(value = "/role/{adminId}")
    @ResponseBody
    public CommonResponse<List<UmsRole>> getRoleList(@PathVariable Long adminId) {
        List<UmsRole> roleList = adminService.getRoleList(adminId);
        return CommonResponseHelper.success(roleList);
    }

    @ApiOperation("获取用户所有资源权限")
    @GetMapping(value = "/resource")
    @ResponseBody
    public CommonResponse<List<UmsResource>> getResourceList(@RequestParam Long adminId,
                                                             @RequestParam(value = "menuId", required = false) Long menuId) {
        List<UmsResource> permissionList = adminService.getResourceList(adminId, menuId);
        return CommonResponseHelper.success(permissionList);
    }

    @ApiOperation("获取用户所有组织机构")
    @GetMapping(value = "/organization/{adminId}")
    @ResponseBody
    public CommonResponse<List<UmsOrganization>> getOrgList(@PathVariable Long adminId) {
        List<UmsOrganization> roleList = adminService.getOrgList(adminId);
        return CommonResponseHelper.success(roleList);
    }

    @ApiOperation("后台新增用户信息")
    @PostMapping(value = "/create")
    @ResponseBody
    public CommonResponse<String> create(@RequestBody UmsAdminCreateDTO admin) {
        boolean success = adminService.create(admin);
        if (success) {
            return CommonResponseHelper.success("创建成功");
        }
        return CommonResponseHelper.fail("创建失败");
    }

    @ApiOperation("修改指定用户信息")
    @PostMapping(value = "/update/{id}")
    @ResponseBody
    public CommonResponse<Boolean> update(@PathVariable Long id, @RequestBody UmsAdminCreateDTO admin) {
        boolean success = adminService.update(id, admin);
        if (success) {
            return CommonResponseHelper.success("更新成功");
        }
        return CommonResponseHelper.fail("更新失败");
    }

    @ApiOperation("修改指定用户密码")
    @PostMapping(value = "/updatePassword")
    @ResponseBody
    public CommonResponse<Integer> updatePassword(@Validated @RequestBody UpdateAdminPasswordParamDTO updatePasswordParam) {
        int status = adminService.updatePassword(updatePasswordParam);
        if (status > 0) {
            return CommonResponseHelper.success(status);
        } else if (status == -1) {
            return CommonResponseHelper.fail("提交参数不合法");
        } else if (status == -2) {
            return CommonResponseHelper.fail("找不到该用户");
        } else if (status == -3) {
            return CommonResponseHelper.fail("旧密码错误");
        } else {
            return CommonResponseHelper.fail();
        }
    }

    @ApiOperation("删除指定用户信息")
    @PostMapping(value = "/delete/{id}")
    @ResponseBody
    public CommonResponse<?> delete(@PathVariable Long id) {
        boolean success = adminService.delete(id);
        if (success) {
            return CommonResponseHelper.success(null);
        }
        return CommonResponseHelper.fail();
    }

    @ApiOperation("修改帐号状态")
    @PostMapping(value = "/updateStatus/{id}")
    @ResponseBody
    public CommonResponse<?> updateStatus(@PathVariable Long id, @RequestParam(value = "status") Integer status) {
        UmsAdminCreateDTO umsAdmin = new UmsAdminCreateDTO();
        umsAdmin.setStatus(status);
        boolean success = adminService.update(id, umsAdmin);
        if (success) {
            return CommonResponseHelper.success(null);
        }
        return CommonResponseHelper.fail();
    }

    @ApiOperation("给用户分配角色")
    @PostMapping(value = "/role/update/{adminId}")
    @ResponseBody
    public CommonResponse<?> updateRole(@PathVariable Long adminId,
                                     @RequestBody List<Long> roleIds) {
        int count = adminService.updateRole(adminId, roleIds);
        if (count >= 0) {
            return CommonResponseHelper.success(count);
        }
        return CommonResponseHelper.fail();
    }

    @ApiOperation(value = "根据用户ID批量查用户")
    @PostMapping(value = "/queryBatchByAdminId")
    @ResponseBody
    public CommonResponse<List<AdminDTO>> queryBatchByEmployee(@RequestBody List<String> adminIdList) {
        List<AdminDTO> dtoList = new ArrayList<>();
        if (CollectionUtil.isEmpty(adminIdList)) {
            return CommonResponseHelper.success(dtoList);
        }
        List<UmsAdmin> adminList = adminService.getBaseMapper().selectBatchIds(adminIdList);
        if (CollectionUtils.isNotEmpty(adminList)) {
            for (UmsAdmin admin : adminList) {
                AdminDTO dto = BeanCopyUtils.copy(admin, AdminDTO.class);
                if (StrUtil.isEmpty(dto.getOrgFullName())) {
                    List<UmsOrganization> adminOrg = adminService.getOrgList(dto.getId());
                    dto.setOrgFullName(CollectionUtils.isNotEmpty(adminOrg) ? adminOrg.get(0).getOrgName() : StrUtil.EMPTY);
                }
                dtoList.add(dto);
            }
        }
        return CommonResponseHelper.success(dtoList);
    }

    @ApiOperation(value = "模糊查询员工信息（限制前25条数据）")
    @GetMapping(value = "/fuzzyQueryByName")
    public CommonResponse<List<AdminDTO>> fuzzyQueryByName(@RequestParam(required = false) String username) {
        return CommonResponseHelper.success(adminService.fuzzyQueryByName(username));
    }

    @ApiOperation(value = "模糊查询员工信息")
    @GetMapping(value = "/fuzzyQueryAllByName")
    public CommonResponse<List<AdminDTO>> fuzzyQueryAllByName(@RequestParam String username) {
        return CommonResponseHelper.success(adminService.fuzzyQueryAllByName(username));
    }

    @ApiOperation(value = "修改直属上级")
    @PostMapping(value = "/editDirectLeader")
    public CommonResponse<?> editDirectLeader(@RequestBody AdminDTO admin) {
        if (StrUtil.equals(admin.getUsername(), admin.getDirectLeader())) {
            throw new BusinessException("直属上级不能是自己");
        }
        adminService.update(new UpdateWrapper<UmsAdmin>().lambda()
                .set(UmsAdmin::getDirectLeader, admin.getDirectLeader())
                .eq(UmsAdmin::getId, admin.getId()));
        return CommonResponseHelper.success();
    }

    @ApiOperation(value = "根据用户ID批量查用户")
    @PostMapping(value = "/queryBatchByAdminIdList")
    @ResponseBody
    public CommonResponse<List<AdminDTO>> queryBatchByAdminIdList(@RequestBody List<String> adminIdList) {
        List<AdminDTO> dtoList = new ArrayList<>();
        if (CollectionUtil.isEmpty(adminIdList)) {
            return CommonResponseHelper.success(dtoList);
        }
        List<UmsAdmin> adminList = adminService.getBaseMapper().selectBatchIds(adminIdList);
        dtoList = Convert.toList(AdminDTO.class,adminList);
        return CommonResponseHelper.success(dtoList);
    }

}
